package ink.xiaobaibai.common;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @description: 数据库中月费用户的定时任务对象
 * @author: 小白白
 * @create: 2021-06-01
 **/

@Data
public class TimedTask {

    /**
     * 时间段每天00:01分更新,加入执行链中,加入时会检验当前月费是否有效
     */
    public static transient String redisKey = "timeTaskObj:";

    private List<TimeNode> timeNodeList;

    /**
     * 加时间段
     * 返回是否成功
     */
    public boolean addTimeNode(Date startDate, Date endDate) {
        TimeNode timeNode = new TimeNode(startDate, endDate);
        if (!this.validTimeNode(timeNode)) {
            return false;
        }
        this.timeNodeList.add(timeNode);
        this.timeNodeList.sort((o1, o2) -> (int) (o1.getStartTime().getTime() - o2.getStartTime().getTime()));
        return true;
    }

    private boolean validTimeNode(TimeNode timeNode) {
        //起始时间检验
        if (timeNode.sHour >= 24 || timeNode.eHour >= 24 || timeNode.sHour < 0 || timeNode.eHour < 0 || timeNode.sMin >= 60 || timeNode.eMin >= 60 || timeNode.eMin < 0 || timeNode.sMin < 0) {
            return false;
        }
        if (timeNode.sHour.equals(timeNode.eHour) && timeNode.sMin >= timeNode.eMin) {
            return false;
        }
        if (timeNode.sHour > timeNode.eHour) {
            return false;
        }
        if (this.timeNodeList == null) {
            this.timeNodeList = new ArrayList<>();
            return true;
        }
        if (this.timeNodeList.size() == 0) {
            return true;
        }
        for (TimeNode node : this.timeNodeList) {
            Integer sHour = node.sHour;
            Integer sMin = node.sMin;
            Integer eHour = node.eHour;
            Integer eMin = node.eMin;
            //新添加的尾与已有的前交叉
            if (timeNode.eHour >= sHour && timeNode.eHour <= eHour && timeNode.eMin >= sMin && timeNode.eMin <= eMin) {
                return false;
            }
            //新添加的头与已有的后交叉
            if (timeNode.sHour >= sHour && timeNode.sHour <= eHour && timeNode.sMin >= sMin && timeNode.sMin <= eMin) {
                return false;
            }
            //新添加的包含已有的
            if (timeNode.sHour <= sHour && timeNode.eHour >= eHour && timeNode.sMin <= sMin && timeNode.eMin >= eMin) {
                return false;
            }
        }
        return true;
    }

    /**
     * data转 HH:mm
     */
    private static int[] dateConvertToHHmm(Date date) {
        String format = DateFormatUtils.format(date, "HH:mm");
        int[] arr = new int[2];
        arr[0] = Integer.parseInt(format.substring(0, 2));
        arr[1] = Integer.parseInt(format.substring(3, 5));
        return arr;
    }

    /**
     * HH:mm转 当天的时间点
     */
    private static Date HHmmConvertToDate(Integer hour, Integer min) {
        Calendar calendar = Calendar.getInstance();
        //可以
        calendar.set(Calendar.HOUR, hour);
        calendar.set(Calendar.MINUTE, min);
        return calendar.getTime();
    }

    /**
     * 任务时间段
     */
    @Data
    @NoArgsConstructor
    public static class TimeNode {
        private Integer sHour;
        private Integer sMin;
        private Integer eHour;
        private Integer eMin;
        private transient Date startTime;
        private transient Date endTime;

        public TimeNode(Date startDate, Date endDate) {
            int[] sArr = dateConvertToHHmm(startDate);
            this.sHour = sArr[0];
            this.sMin = sArr[1];
            int[] eArr = dateConvertToHHmm(endDate);
            this.eHour = eArr[0];
            this.eMin = eArr[1];
            this.startTime = HHmmConvertToDate(this.sHour, this.sMin);
            this.endTime = HHmmConvertToDate(this.eHour, this.eMin);
        }

        public Date getStartTime() {
            return HHmmConvertToDate(this.sHour, this.sMin);
        }

        public Date getEndTime() {
            return HHmmConvertToDate(this.eHour, this.eMin);
        }
    }

}
